package models.admin;

import com.google.gson.Gson;
import models.BaseModel;
import models.constants.AvailableStatus;
import org.apache.commons.collections.map.HashedMap;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import util.common.ConvertUtil;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by liming on 16/7/1.
 */
@Entity
@Table(name = "admin_menu")
public class AdminMenu extends BaseModel {
    /**
     * 菜单编号
     */
    @Column(name = "code")
    public String code;

    /**
     * 菜单名称
     */
    @Column(name = "name")
    public String name;

    /**
     * 当前状态  禁用\可用
     */
    @Column(name = "available_status")
    @Enumerated(EnumType.STRING)
    public AvailableStatus status;


    /**
     * 备注
     */
    @Column(name = "remark")
    public String remark;

    /**
     * 根据业务菜单ID获取业务
     *
     * @param menuId
     */
    public final static String SQL_MENU_BIZ_OPT = "select a.id,a.name,b.id as operate_id,b.name as operate_name " +
            " from (" +
            " select b.id,b.name,max(a.id) as show_order" +
            " from admin_menu_item a" +
            " left join admin_business b on a.business_id = b.id" +
            " where a.menu_id = %d and a.business_id>0" +
            " group by b.id,b.name" +
            ") a left join admin_business_operate b on a.id = b.business_id" +
            " order by a.show_order,b.id";

    public static List<Map<String, Object>> loadMenuBusiness(long menuId) {
        List<Map<String, Object>> businessList = new ArrayList<>();
        long currentBizId = 0;
        Query query = em().createNativeQuery(String.format(SQL_MENU_BIZ_OPT, menuId));
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String, Object>> baseBizList = query.getResultList();
        for (Map<String, Object> baseBiz : baseBizList) {
            long bizId = ConvertUtil.toLong(baseBiz.get("id"));
            String bizName = ConvertUtil.toString(baseBiz.get("name"));
            long optId = ConvertUtil.toLong(baseBiz.get("operate_id"));
            String optName = ConvertUtil.toString(baseBiz.get("operate_name"));
            if (bizId != currentBizId) {
                Map<String, Object> bizMap = new HashMap<>();
                List<Map<String, Object>> optList = new ArrayList<>();
                bizMap.put("id", bizId);
                bizMap.put("name", bizName);
                bizMap.put("operateList", optList);
                businessList.add(bizMap);
                currentBizId = bizId;
            }
            Map<String, Object> optMap = new HashMap<>();
            optMap.put("id", optId);
            optMap.put("name", optName);
            ((List<Map<String, Object>>) businessList.get(businessList.size() - 1).get("operateList")).add(optMap);
        }

        return businessList;
    }

    /**
     * 根据用户ID获取系统菜单
     *
     * @param userId
     * @return
     */
    public final static String SQL_USER_MENU = "select c.parent_id,c.id,c.name,ifnull(c.business_id,0) as business_id,d.url" +
            " from admin_user_role a" +
            " left join admin_role b on a.admin_role_id = b.id" +
            " left join admin_menu_item c on b.menu_id = c.menu_id" +
            " left join admin_business d on c.business_id = d.id" +
            " where a.admin_user_id = %d and (c.business_id is null or(c.business_id is not null and EXISTS(" +
            " select 1 from admin_role_operate aro " +
            " left join admin_business_operate abo on aro.admin_biz_operate_id = abo.id" +
            " where a.admin_role_id = aro.admin_role_id and c.business_id = abo.business_id" +
            "))) order by c.parent_id,c.show_order,c.id";

    public static List<Map<String, Object>> loadMenuByUserId(long userId) {
        List<Map<String, Object>> menuList = new ArrayList<>();
        Map<Long, List<Map<String, Object>>> childrenMap = new HashedMap();
        Query query = em().createNativeQuery(String.format(SQL_USER_MENU, userId));
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String, Object>> baseMenuList = query.getResultList();
        //第一遍创建根据父节点找孩子的Map
        for (Map<String, Object> menu : baseMenuList) {
            long parentId = ConvertUtil.toLong(menu.get("parent_id"));
            if (parentId > 0) {
                if (!childrenMap.containsKey(parentId))
                    childrenMap.put(parentId, new ArrayList<Map<String, Object>>());
                childrenMap.get(parentId).add(menu);
            } else {
                menuList.add(menu);
            }
        }
        Gson gson = new Gson();
        return loadChildren(menuList, childrenMap);

    }

    /**
     * 递归找孩子
     *
     * @param menuList
     * @param childrenMap
     * @return
     */
    public static List<Map<String, Object>> loadChildren(List<Map<String, Object>> menuList, Map<Long, List<Map<String, Object>>> childrenMap) {
        for (Map<String, Object> menu : menuList) {
            long menuId = ConvertUtil.toLong(menu.get("id"));
            if (childrenMap.containsKey(menuId)) {
                List<Map<String, Object>> children = childrenMap.get(menuId);
                menu.put("children", children);
                loadChildren(children, childrenMap);
            } else {
                menu.put("children", new ArrayList<Map<String, Object>>());
            }
        }
        return menuList;
    }

}
